/*
 * MenuBar.java
 * 
 * Created by demory on Mar 29, 2009, 4:08:11 PM
 * 
 * Copyright 2008 David D. Emory
 * 
 * This file is part of Five Points. See <http://www.fpdev.org> for
 * additional information regarding the project.
 * 
 * Five Points is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * Five Points is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with Five Points.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.fpdev.apps.cart.gui;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import org.fpdev.apps.cart.CartEvent;
import org.fpdev.apps.cart.CartEventProcessor;
import org.fpdev.apps.cart.Editor;
import org.fpdev.apps.cart.gui.control.ControlFrame;

/**
 *
 * @author demory
 */
public class MenuBar extends JMenuBar implements ActionListener {

  private CartEventProcessor ceh_;

  private JMenu recentFilesMenu_;

  private MenuItem undoItem_, redoItem_;

  private Set<EditorPropCheckBoxMenuItem> edPropItems_;

  public MenuBar(CartEventProcessor ceh, CartGUI gui, List<String> recentFiles) {
    super();
    ceh_ = ceh;
    edPropItems_ = new HashSet<EditorPropCheckBoxMenuItem>();

    JMenu fileMenu = new JMenu("File");
    newMenuItem(fileMenu, "New", CartEvent.Type.FILE_NEW);
    newMenuItem(fileMenu, "Open...", CartEvent.Type.FILE_LOAD);
    
    recentFilesMenu_ = new JMenu("Open Recent File");
    updateRecentFilesMenu(recentFiles);
    fileMenu.add(recentFilesMenu_);

    fileMenu.addSeparator();
    newMenuItem(fileMenu, "Save", CartEvent.Type.FILE_SAVE);
    newMenuItem(fileMenu, "Save As...", CartEvent.Type.FILE_SAVE_AS);
    fileMenu.addSeparator();
    newMenuItem(fileMenu, "Exit", CartEvent.Type.FILE_EXIT);
    add(fileMenu);

    JMenu editMenu = new JMenu("Edit");
    undoItem_ = newMenuItem(editMenu, "Undo", CartEvent.Type.EDIT_UNDO);
    redoItem_ = newMenuItem(editMenu, "Redo", CartEvent.Type.EDIT_REDO);
    add(editMenu);


    JMenu toolsMenu = new JMenu("Tools");
    newMenuItem(toolsMenu, "Record Movie", CartEvent.Type.TOOLS_MOVIE);
    newMenuItem(toolsMenu, "Run Bundler", CartEvent.Type.TOOLS_BUNDLER);
    add(toolsMenu);

    JMenu viewMenu = new JMenu("View");
    newEPCBMenuItem(viewMenu, "Show Anchors", Editor.Property.SHOW_ANCHORS);
    newEPCBMenuItem(viewMenu, "Show Corridors", Editor.Property.SHOW_CORRIDORS);
    newEPCBMenuItem(viewMenu, "Show Lines", Editor.Property.SHOW_LINES);
    viewMenu.addSeparator();
    newEPCBMenuItem(viewMenu, "Show Grid", Editor.Property.SHOW_GRID);
    newEPCBMenuItem(viewMenu, "Snap to Grid", Editor.Property.SNAP_TO_GRID);
    viewMenu.addSeparator();
    newEPCBMenuItem(viewMenu, "Use Antialiasing", Editor.Property.USE_ANTIALIASING);
    add(viewMenu);


    JMenu windowMenu = new JMenu("Window");
    for(final ControlFrame frame : gui.getControlFrameManager().getFrames()) {
      final JCheckBoxMenuItem item = new JCheckBoxMenuItem(frame.getTitle());
      frame.setMenuItem(item);
      item.addItemListener(new ItemListener() {
        public void itemStateChanged(ItemEvent e) {
          frame.setVisible(item.isSelected());
          //System.out.println("iSC "+item.isSelected());
        }
      });
      windowMenu.add(item);
    }
    add(windowMenu);

  }

  public MenuItem getUndoItem() {
    return undoItem_;
  }

  public MenuItem getRedoItem() {
    return redoItem_;
  }

  public void actionPerformed(ActionEvent e) {
    if(e.getSource() instanceof MenuItem) {
      ceh_.handleEvent(new CartEvent(((MenuItem) e.getSource()).evType_));
    }
  }

  public void updateRecentFilesMenu(List<String> recentFiles) {
    recentFilesMenu_.removeAll();
    for(final String filename : recentFiles) {
      JMenuItem item = new JMenuItem(filename);
      recentFilesMenu_.add(item);
      item.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
          CartEvent evt = new CartEvent(CartEvent.Type.FILE_LOAD);
          evt.setProperty("filename", filename);
          ceh_.handleEvent(evt);
        }
      });
    }
    recentFilesMenu_.addSeparator();
    newMenuItem(recentFilesMenu_, "Clear Recent Files", CartEvent.Type.FILE_CLEAR_RECENT);
  }

  private MenuItem newMenuItem(JMenu menu, String name, CartEvent.Type cmd) {
    MenuItem item = new MenuItem(name, cmd);
    item.addActionListener(this);
    menu.add(item);
    return item;
  }

  public class MenuItem extends JMenuItem {

    private CartEvent.Type evType_;

    public MenuItem(String name, CartEvent.Type evType) {
      super(name);
      evType_ = evType;
    }
  }

  private void newEPCBMenuItem(JMenu menu, String title, Editor.Property prop) {
    EditorPropCheckBoxMenuItem item = new EditorPropCheckBoxMenuItem(title, prop);
    edPropItems_.add(item);
    menu.add(item);
  }

  public void updateEdPropItems(Editor ed) {
    for(EditorPropCheckBoxMenuItem item : edPropItems_)
      item.setSelected(ed.getBoolProperty(item.prop_));
  }

  private class EditorPropCheckBoxMenuItem extends JCheckBoxMenuItem {

    private Editor.Property prop_;

    public EditorPropCheckBoxMenuItem(String title, Editor.Property prop) {
      super(title);
      prop_ = prop;
      addItemListener(new ItemListener() {
        public void itemStateChanged(ItemEvent e) {
          CartEvent ev = new CartEvent(CartEvent.Type.MODIFY_EDITOR_PROPERTY);
          ev.setProperty("property", prop_);
          ev.setProperty("value", isSelected() ? "true" : "false");
          ceh_.handleEvent(ev);
        }
      });
    }
  }
}
